package com.miuugo.common.tools;


import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 */
public class DateUtils {

    /**
     * 年-月-日 显示格式
     */
    public static final String DATE_TO_STRING_SHORT_PATTERN = "yyyy-MM-dd";
    /**
     * 年-月-日 时:分:秒 显示格式
     */
    // 备注:如果使用大写HH标识使用24小时显示格式,如果使用小写hh就表示使用12小时制格式。
    public static final String DATE_TO_STRING_DETAIAL_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * Date类型转为指定格式的String类型
     *
     * @param source
     * @param pattern
     * @return
     */
    public static String dateToString(Date source, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(source);
    }

    /**
     * unix时间戳转为指定格式的String类型
     * System.currentTimeMillis()获得的是是从1970年1月1日开始所经过的毫秒数
     * unix时间戳:是从1970年1月1日（UTC/GMT的午夜）开始所经过的秒数,不考虑闰秒
     *
     * @param source
     * @param pattern
     * @return
     */
    public static String timeStampToString(long source, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        Date date = new Date(source * 1000);
        return simpleDateFormat.format(date);
    }

    /**
     * 将日期转换为时间戳(unix时间戳,单位秒)
     *
     * @param date
     * @return
     */
    public static long dateToTimeStamp(Date date) {
        Timestamp timestamp = new Timestamp(date.getTime());
        return timestamp.getTime() / 1000;
    }

    /**
     * 字符串转换为对应日期(可能会报错异常)
     * @param source
     * @param pattern
     * @return
     */
    public static Date stringToDate(String source, String pattern) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            return simpleDateFormat.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("时间转换失败");
        }
    }

    /**
     * 获得当前时间对应的指定格式
     * @param pattern
     * @return
     */
    public static String currentFormatDate(String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(new Date());

    }

    /**
     * 获得当前时间对应的指定格式
     * @param pattern
     * @return
     */
    public static Date currentFormatDateToDate(String pattern) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.parse(simpleDateFormat.format(new Date()));
    }

    /**
     * 获得指定时间指定格式
     * @param pattern
     * @return
     */
    public static Date getPattenDate(String pattern, Date date) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.parse(simpleDateFormat.format(date));
    }

    /**
     * 获取今天的最后时间 23:59:59
     */
    @SuppressWarnings("all")
    public static Date getLastTimeOfToday() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    /**
     * 获取今天的开始时间 00:00:00
     * @return
     */
    @SuppressWarnings("all")
    public static Date getStartTimeOfToday() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * 获取传入时间上一天日期
     * @param date
     * @return
     */
    public static Date getBeforeDate(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 获取传入时间的月份
     */
    public static int getMonthByDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        //注意月份是从0开始的,比如当前7月，获得的month为6，所以做+1处理
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取两个时间区间的月份
     * @param minDate
     * @param maxDate
     * @return
     * @throws RuntimeException
     */
    public static List<String> getMonthBetween(Date minDate, Date maxDate) {
        try {
            ArrayList<String> result = new ArrayList<String>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();

            min.setTime(minDate);
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(maxDate);
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            Calendar curr = min;
            while (curr.before(max)) {
                result.add(sdf.format(curr.getTime()));
                curr.add(Calendar.MONTH, 1);
            }

            return result;
        } catch (Exception e) {
            throw new RuntimeException("时间转换失败");
        }
    }

    /**
     * 获取传入时间月的第一天
     * @param monthDate
     * @return
     */
    @SuppressWarnings("all")
    public static Date getFirstDayByMonth(Date monthDate) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(monthDate);
        // 获取前月的第一天
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        cale.set(Calendar.HOUR, 0);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    /**
     * 获取传入时间月的最后一天
     * @param monthDate
     * @return
     */
    @SuppressWarnings("all")
    public static Date getLastDayByMonth(Date monthDate) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(monthDate);
        // 获取前月的最后
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        cale.set(Calendar.HOUR_OF_DAY, 23);
        cale.set(Calendar.MINUTE, 59);
        cale.set(Calendar.SECOND, 59);
        cale.set(Calendar.MILLISECOND, 999);
        return cale.getTime();
    }

    /**
     *
     * @param date
     * @return
     */
    public static Date minInDay(Date date) {
        if(date == null) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date minInNextDay(Date date) {
        if(date == null) return null;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static void main(String[] args) {
        Date firstDayByMonth = getFirstDayByMonth(new Date());
        Date lastDayByMonth = getLastDayByMonth(new Date());
        System.out.println("开始时间：" + firstDayByMonth);
        System.out.println("结束时间：" + lastDayByMonth);
    }
}
